<?php

namespace App\Ad\Docking;

use App\Ad\MediaApi\Gdt\GdtZhgyApi;
use App\Commons\CommonConstant;
use App\Datalog\AdMonitorLog;
use App\Models\AdMonitor;
use App\Models\AdPlan;
use App\Models\FirstupAd;
use App\Models\Firstups;
use App\Models\GameChannel;
use App\Models\Log\LogAdMonitor;
use App\Models\Log\LogAdMonitorInfo;
use App\Models\Log\LogAdPostbackMedia;
use App\Services\GameChannelService;
use Illuminate\Http\Request;

// 广点通-转化跟踪-小游戏
class GdtZhgyXyx extends DockingBase
{
    // 点击监控参数
    protected $monitorParams = [
        'click_id'              => '__CLICK_ID__',                // 点击id
        'click_time'            => '__CLICK_TIME__',              // 点击时间
        'impression_time'       => '__IMPRESSION_TIME__',         // 曝光时间
        'campaign_id'           => '__CAMPAIGN_ID__',             // 计划id
        'adgroup_id'            => '__ADGROUP_ID__',              // 广告组id（实际为广告id）
        'ad_id'                 => '__AD_ID__',                   // 广告id（实际为创意id）
        'adgroup_name'          => '__ADGROUP_NAME__',            // 广告组名称
        'site_set_name'         => '__SITE_SET_NAME__',           // 广告版位
        'campaign_name'         => '__CAMPAIGN_NAME__',           // 计划名称
        'ad_name'               => '__AD_NAME__',                 // 广告名称
        'ad_platform_type'      => '__AD_PLATFORM_TYPE__',        // 广告投放平台
        'ad_type'               => '__AD_TYPE__',                 // 广告类型
        'account_id'            => '__ACCOUNT_ID__',              // 广告主id
        'agency_id'             => '__AGENCY_ID__',               // 代理商id
        'click_sku_id'          => '__CLICK_SKU_ID__',            // 点击sku
        'billing_event'         => '__BILLING_EVENT__',           // 计费类型
        'page_url'              => '__PAGE_URL__',                // 落地页地址
        'device_os_type'        => '__DEVICE_OS_TYPE__',          // 设备类型
        'process_time'          => '__PROCESS_TIME__',            // 请求时间
        'promoted_object_id'    => '__PROMOTED_OBJECT_ID__',      // 应用id
        'promoted_object_type'  => '__PROMOTED_OBJECT_TYPE__',    // 推广类型
        'request_id'            => '__REQUEST_ID__',              // 请求id
        'impression_id'         => '__IMPRESSION_ID__',           // 曝光id
        'callback'              => '__CALLBACK__',                // 回传接口的 url
        'encrypted_position_id' => '__ENCRYPTED_POSITION_ID__',   // 联盟广告位id
        'wechat_openid'         => '__WECHAT_OPEN_ID__',          // 专用于网页类小程序转化规则的点击监测下发
        'keyword_id'            => '__KEYWORD_ID__',              // 专用于搜索广告的关键词ID
        'keyword_text'          => '__KEYWORD_TEXT__',            // 专用于搜索广告的关键词
    ];

    // 转化类型映射
    protected $eventTypeMap = [
        CommonConstant::EVENT_REG => 'REGISTER',
        CommonConstant::EVENT_PAY => 'PURCHASE',
    ];

    // 此接口由子类继承
    // 获得点击监控链接拼接参数
    public function getMonitorParams($device_type): string
    {
        return http_build_query($this->monitorParams);
    }

    // 此接口由子类继承
    // 处理落地监控数据
    public function handleMonitorInfo(Request $request)
    {
        // 待匹配日志
        $params           = $request->all();
        $log              = LogAdMonitor::suffix(date('Ym'));
        $log->create_time = time();
        $log->plan_id     = $params['plan_id'];
        $log->ip          = $params['ip'] ?? '';
        $log->click_id    = $params['impression_id'];
        $log->openid      = $params['wechat_openid'] ?? '';
        $log->save();

        // 完整日志
        $info              = LogAdMonitorInfo::suffix(date('Ym'));
        $info->create_time = time();
        $info->plan_id     = $params['plan_id'];
        $info->monitor_id  = $log->id;
        $info->data        = json_encode($params, JSON_UNESCAPED_UNICODE);
        $info->save();

        // 落地日志
        AdMonitorLog::getInstance()->addLog($log, $info);

        return yqok();
    }

    /**
     * 此接口由子类继承
     * 根据媒体加密方式-生成对应的设备码，用于匹配
     * @param int      $device_type 设备类型
     * @param string[] $device_nums 设备码
     * @return array
     */
    public function getMonitorDeviceNum($device_type, $device_nums): array
    {
        $data = [];
        foreach ($device_nums as $key => $val) {
            switch ($key) {
                case 'click_id':
                    $data[$key] = $val;
                    break;
                case 'openid':
                    $data[$key] = $val;
                    break;
            }
        }

        return $data;
    }

    /**
     * 此接口由子类继承
     * 将用户行为进行api上报转化，如激活注册付费
     *
     * @param int $event_type 事件类型 如激活注册付费
     * @param AdMonitor $monitor
     * @param FirstupAd $firstup_ad
     * @param mixed $mod 事件对应的模型 激活 Firstup 注册 Users 付费 Orders
     * @return int 处理结果状态
     */
    public function postbackToMedia($event_type, AdMonitor $monitor, FirstupAd $firstup_ad, $mod): int
    {
        // 此事件不需要上报
        if (!isset($this->eventTypeMap[$event_type])) {
            return LogAdPostbackMedia::STATUS_NONEED;
        }

        $plan = AdPlan::find($firstup_ad->plan_id);

        // 如果非API自上报则无需处理
        if ($plan['access_type'] != AdPlan::ACCESS_TYPE_API) {
            return LogAdPostbackMedia::STATUS_NOTAPI;
        }

        $firstup = Firstups::find($firstup_ad->firstup_id);
        if (!$firstup) {
            return LogAdPostbackMedia::STATUS_FAIL;
        }

        $game_channel = GameChannelService::getInstance()->get($firstup->game_channel_id, true);
        $monitor_data = json_decode($monitor->data, true);

        $actions = [
            'outer_action_id' => "{$firstup_ad->id}_{$mod->id}",
            'action_time'     => $mod->create_time,
            'user_id'         => [
                'wechat_app_id' => $game_channel['appid'],
                'wechat_openid' => $monitor_data['wechat_openid'],
            ],
            'trace' => [
                'click_id' => $monitor_data['click_id'],
            ],
            'action_type' => $this->eventTypeMap[$event_type],
        ];

        // 如果是充值加传金额
        $is_pay = $event_type == CommonConstant::EVENT_PAY;
        if ($is_pay) {
            $actions['action_param']['value'] = $mod->call_money * 100;
        }

        // 不存在callback
        if (!isset($monitor_data['callback'])) {
            return LogAdPostbackMedia::STATUS_NOCALLBACK;
        }

        $url = $monitor_data['callback'];
        $res = GdtZhgyApi::getInstance()->sendConv($url, $actions);

        if ($res !== true) {
            return LogAdPostbackMedia::STATUS_FAIL;
        }

        return LogAdPostbackMedia::STATUS_SUCC;
    }

    // 此接口由子类继承
    // 匹配成功后补齐监控数据
    public function supplementMonitorInfo(FirstupAd $firstup_ad, AdMonitor $monitor)
    {
        $data = json_decode($monitor->data, true);

        $firstup_ad->advertiser_id    = $data['account_id'] ?? 0;        // 广告主id
        $firstup_ad->campaign_id      = $data['campaign_id'] ?? 0;       // 推广计划id
        $firstup_ad->adgroup_id       = $data['adgroup_id'] ?? 0;        // 广告组id（实际为广告id）
        $firstup_ad->ad_id            = $data['ad_id'] ?? 0;             // 广告id（实际为创意id）
        $firstup_ad->campaign_name    = $data['campaign_name'] ?? '';    // 推广计划名称
        $firstup_ad->adgroup_name     = $data['adgroup_name'] ?? '';     // 广告组名称
        $firstup_ad->ad_name          = $data['ad_name'] ?? '';          // 广告名称
        $firstup_ad->site_set_name    = $data['site_set_name'] ?? '';    // 广告版位
        $firstup_ad->ad_platform_type = $data['ad_platform_type'] ?? 0;  // 广告投放平台
        $firstup_ad->ad_type          = $data['ad_type'] ?? 0;           // 广告类型
        $firstup_ad->billing_event    = $data['billing_event'] ?? 0;     // 计费类型
    }
}
